using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace Dragoon
{
    /// <summary>
    /// A Dragoon exception
    /// </summary>
    public class ExDragoon : System.Exception
    {
        internal ExDragoon(string message) : base(message) {}
        internal ExDragoon(string format, params object[] args)         
            : base(string.Format(format,args)){}
    }

    public interface ISet<TValue, TKey> 
    {
        TKey KeyOf(TValue elem);
        bool ContainsKeyOf(TValue elem);
        TValue this[TKey index]
        {
            get;
        }
    }

    public abstract class Set<TValue, TKey> : ISet<TValue, TKey>
        where TKey : IEquatable<TKey>
    {
        private IDictionary<TKey, TValue> _dictionary = new Dictionary<TKey,TValue>();

        public void Add(TValue[] values)
        {
            foreach (TValue v in values)
                Add(v);
        }

        abstract public TKey KeyOf(TValue elem);

        public void Add(TValue elem)
        {
            if (ContainsKeyOf(elem))
                throw new ExDragoon("Cannot add element with key '{0}'.  It is already in the set.", KeyOf(elem));
            _dictionary.Add(new KeyValuePair<TKey, TValue>(KeyOf(elem), elem));
        }

        public bool ContainsKeyOf(TValue elem)
        {
            return _dictionary.ContainsKey(KeyOf(elem));
        }

        public TValue this[TKey index]
        {
            get
            {
                try
                {
                    return _dictionary[index];
                }
                catch (KeyNotFoundException)
                {
                    throw new ExDragoon("{0} not found for key '{1}'",typeof(TValue),index);
                }
            }
        }

    }

}
